<?php
class Error
{
	/**
	 * список сообщений об обшибках
	 *
	 * @var array of ErrorItem
	 */
	var $error_log;	
	
	var $config;
	
	function Error()
	{
		global $cfg;
		$this->config=&$cfg['error'];
		$this->error_log=array();
		set_error_handler(array(&$this,'ErrorHandler'));
		register_shutdown_function(array(&$this,'Destructor'));
	}
	
	
	function ErrorHandler($errno, $errstr, $errfile, $errline)
	{
		$error=new ErrorItem(&$errno,&$errstr,&$errfile,&$errline);
		$this->error_log[]=$error;
		$current_error_level=error_reporting();
		if ($current_error_level & $errno)
	    {
        	print $error->DumpHtml();
	    }
	}
	
	function Destructor()
	{
		$add='';
		if ( function_exists('apache_request_headers') )
		{
			$add.='REQUEST:' . var_export(apache_request_headers(),true) . "\n";			
		}
		$error_to_log=$add;
		$error_to_mail=$add;
		while( list(,$error_item)=each($this->error_log) )
		{
			$error_to_log.=strip_tags($error_item->DumpText());
			if ( isset($this->config['mail_level']) && ($error_item->errno & $this->config['mail_level']) )
			{
				$error_to_mail.=strip_tags($error_item->DumpText());
			}
		}
		/**
		 * @TODO отправляем лог ошибок на e-mail и записываем в файл
		 */
		logg($error_to_log);
		
		if ( isset($this->config['mail_level']) && $this->config['mail_level'] && isset($this->config['mail']) && $this->config['mail'] )
		{
			
			mail( $this->config['mail'] , 'error message'.(isset($_SERVER['SERVER_NAME'])?' ['.$_SERVER['SERVER_NAME'].']':'') , $error_to_mail );
		}
	}
	
}
class ErrorItem
{
	var $errno;
	var $errstr;
	var $errfile;
	var $errline;
	var $backtrace;
	function ErrorItem($errno,$errstr,$errfile,$errline)
	{
		$this->errno=&$errno;
		$this->errstr=&$errstr;
		$this->errfile=&$errfile;
		$this->errline=&$errline;
		$t=debug_backtrace();
		array_shift($t);array_shift($t);
		$this->backtrace=array();
		foreach ((array)$t as $v)
        {
        	$this->backtrace[]=(object)array(
        		'class'=>(isset($v['class']))?$v['class']." : ":'',
        		'function'=>(isset($v['function']))?$v['function']." : ":'',
        		'file'=>(isset($v['file']))?$v['file']." : ":'',
        		'line'=>(isset($v['line']))?$v['line']." : ":'',
        	);
        }
	}

	/**
	 * Алиас для DumpText
	 *
	 * @return plain_text
	 */
	function Dump()
	{
		return $this->DumpText();
	}
	
	/**
	 * возвращаем сообщение об ошибке в формате plain text
	 *
	 * @return plain_text
	 */
	function DumpText()
	{
		$s=$this->errstr." (".$this->errno.") at [".$this->errfile." :: ".$this->errline."]\n";
		foreach ((array)$this->backtrace as $v)
		{
			$s.="\t".$v->class.'->'.$v->function.'() at'.$v->file.' ['.$v->line.']'."\n";
		}
		return $s;
	}
	
	/**
	 * возвращаем сообщение об ошибке в формате html 
	 *
	 * @return html
	 */
	function DumpHtml()
	{
		$s ="<div class='z_error'><p>\n";
		$s.=$this->errstr." (".$this->errno.") at [".$this->errfile." :: ".$this->errline."]\n</p><ul>\n";
		foreach ((array)$this->backtrace as $v)
		{
			$s.='<li>'.$v->class.'->'.$v->function.'() at'.$v->file.' ['.$v->line.']</li>'."\n";
		}
		$s.="</ul></div>\n\n";
		return $s;
	}
}
?>